#Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数。

#首先，我们看看itertools提供的几个“无限”迭代器：

import itertools
import functools

#count()会创建一个无限的迭代器
natuals = itertools.count(1,2)
# for x in natuals:
   # print(x) 


# cycle()会把传入的一个序列无限重复下去
cs = itertools.cycle([1,2])
# for c in cs:
#     print(c)

    
# repeat()负责把一个元素无限重复下去，不过如果提供第二个参数就可以限定重复次数
ns = itertools.repeat("AB",3)
for n in ns:
    print(n)

# 无限序列只有在for迭代时才会无限地迭代下去，如果只是创建了一个迭代对象，它不会事先把无限个元素生成出来，事实上也不可能在内存中创建无限多个元素。

# 无限序列虽然可以无限迭代下去，但是通常我们会通过takewhile()等函数根据条件判断来截取出一个有限的序列# 

ns = itertools.takewhile(lambda x: x <=10,natuals)
print(list(ns))

a = ['1','2','3']
b = 'abc'
for c in itertools.chain(a,b):
    print(c)

c = list(itertools.chain(a,b))
print(c)
d = "".join(c)
print(d)


# groupby()把迭代器中相邻的重复元素挑出来放在一起
for key, group in itertools.groupby("AFFaDDaBFFBbcCAAa", lambda x : x.upper()):
    a = list(group)
    if "a" in a and len(a)>1:
        print(a)



#计算奇数序列的前N项和
def pi(N):
     # step 1: 创建一个奇数序列: 1, 3, 5, 7, 9, ...

    # step 2: 取该序列的前N项: 1, 3, 5, 7, 9, ..., 2*N-1.

    # step 3: 添加正负符号并用4除: 4/1, -4/3, 4/5, -4/7, 4/9, ...
    odds = itertools.count(1,2)
    ns=list(itertools.takewhile(lambda x: x <= N*2, odds))
    cs = itertools.cycle([4,-4])
    sums = functools.reduce(lambda x, y: x+y, map(lambda x : next(cs)/x, ns))
    return sums

f = pi(10)
print(f)

def qi(N):
    odds = (x for x in range(1,N*2,2))
    odds =list(odds)
    sums = functools.reduce(lambda x, y : x+y, map(lambda x :pow(-1,odds.index(x))*4 /x, odds))
    return sums

a = qi(10)
print(a)

print(round(3.87))

a= [1,2,3,4,5]
b ='12345'
print(list(zip(a,b)))

a=[(1,5),(2,),(3,4)]
print(list(zip(*a)))


from html.parser import HTMLParser
from html.entities import name2codepoint

class MyHTMLParser(HTMLParser):

    def handle_starttag(self, tag, attrs):
        print('<%s>' % tag)

    def handle_endtag(self, tag):
        print('</%s>' % tag)

    def handle_startendtag(self, tag, attrs):
        print('<%s/>' % tag)

    def handle_data(self, data):
        # print(data)
        pass

    def handle_comment(self, data):
        print('<!--', data, '-->')

    def handle_entityref(self, name):
        print('&%s;' % name)

    def handle_charref(self, name):
        print('&#%s;' % name)

parser = MyHTMLParser()
parser.feed('''<html>
<head></head>
<body>
<!-- test html parser -->
    <p>Some <a href=\"#\">html</a> HTML&nbsp;tutorial...<br>END</p>
</body></html>''')
